/* 
 *	Copyright (C) 2007 cooleyes
 *	eyes.cooleyes@gmail.com 
 *
 *  This Program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2, or (at your option)
 *  any later version.
 *   
 *  This Program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU General Public License for more details.
 *   
 *  You should have received a copy of the GNU General Public License
 *  along with GNU Make; see the file COPYING.  If not, write to
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
 *  http://www.gnu.org/copyleft/gpl.html
 *
 */
#include "atrac3_codec.h"
#include <stdlib.h>
#include <string.h>
#include <pspaudiocodec.h>

Atrac3Codec::Atrac3Codec() {
	init_flag = false;
};

Atrac3Codec::~Atrac3Codec() {
};

char* Atrac3Codec::initialize(AudioCodecInitData* init_data) {
	audio_samples_per_frame = init_data->samples_per_frame;
	audio_frame_align = init_data->frame_align;
	if ( audio_samples_per_frame == 2048 ) //atrac3plus, 2048 samples per frame ; atrac3, 1024 samples per frame;
		audio_type = 0x1000;
	else
		audio_type = 0x1001;
	if ( audio_type == 0x1000 ) {
		atrac3plus_flag[0] = 0x28;
		atrac3plus_flag[1] = (audio_frame_align >> 3) - 1;
	}
	
	memset(me_audio_codec_buffer, 0, 65*sizeof(uint32_t));
	if ( audio_type == 0x1000 ) {
		me_audio_codec_buffer[5] = 0x1;
		me_audio_codec_buffer[10] = atrac3plus_flag[1];
		me_audio_codec_buffer[10] = (me_audio_codec_buffer[10] << 8) | atrac3plus_flag[0];
		me_audio_codec_buffer[12] = 0x1;
		me_audio_codec_buffer[14] = 0x1;
		if ( sceAudiocodecCheckNeedMem(me_audio_codec_buffer, audio_type) < 0 ) 
			return "Atrac3Codec : sceAudiocodecCheckNeedMem fail";
		if ( sceAudiocodecGetEDRAM(me_audio_codec_buffer, audio_type) < 0 )
			return "Atrac3Codec : sceAudiocodecGetEDRAM fail";
		if ( sceAudiocodecInit(me_audio_codec_buffer, audio_type) < 0 ) {
			sceAudiocodecReleaseEDRAM(me_audio_codec_buffer);
			return "Atrac3Codec : sceAudiocodecInit fail";
		}
	}
	else {
		me_audio_codec_buffer[26] = 0x20;
		if ( sceAudiocodecCheckNeedMem(me_audio_codec_buffer, audio_type) < 0 ) 
			return "Atrac3Codec : sceAudiocodecCheckNeedMem fail";
		if ( sceAudiocodecGetEDRAM(me_audio_codec_buffer, audio_type) < 0 )
			return "Atrac3Codec : sceAudiocodecGetEDRAM fail";
		me_audio_codec_buffer[10] = 4;
		me_audio_codec_buffer[44] = 2;
		if ( audio_frame_align == 0x130 )
			me_audio_codec_buffer[10] = 6;
		if ( sceAudiocodecInit(me_audio_codec_buffer, audio_type) < 0 ) {
			sceAudiocodecReleaseEDRAM(me_audio_codec_buffer);
			return "Atrac3Codec : sceAudiocodecInit fail";
		}
	}
	init_flag = true;
	return 0;
};

void Atrac3Codec::finalize() {
	if( init_flag ) {
		sceAudiocodecReleaseEDRAM(me_audio_codec_buffer);
		init_flag = false;
	}
};

int32_t Atrac3Codec::decode(void* data, uint32_t data_len, void* pcm_data) {
	if( init_flag ) {
		me_audio_codec_buffer[6] = (uint32_t)data;
		me_audio_codec_buffer[8] = (uint32_t)pcm_data;
		if ( sceAudiocodecDecode(me_audio_codec_buffer, audio_type) < 0 )
			return -1;
		return audio_samples_per_frame;
	}
	else
		return -1;
};

